<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>three.js / documentation</title>
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<link type="text/css" rel="stylesheet" href="index.css">
	</head>
	<body>

		<div id="panel" class="collapsed">

			<h1><a href="http://threejs.org">three.js</a> / docs</h1>

			<a id="expandButton" href="#">
				<span></span>
				<span></span>
				<span></span>
			</a>

			<div class="filterBlock" >
				<input type="text" id="filterInput" placeholder="Type to filter">
				<a href="#" id="clearFilterButton">x</a>
			</div>
			<div id="content"></div>

		</div>

		<iframe name="viewer"></iframe>

		<script src="list.js"></script>

		<script>

			var panel = document.getElementById( 'panel' );
			var content = document.getElementById( 'content' );
			var clearFilterButton = document.getElementById( 'clearFilterButton' );
			var expandButton = document.getElementById( 'expandButton' );
			var filterInput = document.getElementById( 'filterInput' );
			var iframe = document.querySelector( 'iframe' );

			var pageProperties = {};
			var titles = {};
			var categoryElements = [];


			// Functionality for hamburger button (on small devices)

			expandButton.onclick = function ( event ) {

				event.preventDefault();
				panel.classList.toggle( 'collapsed' );

			};


			// Functionality for search/filter input field

			filterInput.oninput = function ( event ) {

				updateFilter();

			};


			// Functionality for filter clear button

			clearFilterButton.onclick = function ( event ) {

				event.preventDefault();

				filterInput.value = '';
				updateFilter();

			};

			// Activate content and title change on browser navigation

			window.onpopstate = createNewIframe;

			// Create the navigation panel and configure the iframe

			createNavigation();
			createNewIframe();

			// Navigation Panel

			function createLink( pageName, pageURL ) {

				var link = document.createElement( 'a' );
				link.href = pageURL + '.html';
				link.textContent = pageName;
				link.setAttribute( 'target', 'viewer' );
				link.addEventListener( 'click', function ( event ) {

					window.location.hash = pageURL;
					panel.classList.add( 'collapsed' );

				} );

				return link;

			}

			function createNavigation() {

				// Create the navigation panel using data from list.js

				var navigation = document.createElement( 'div' );
				content.appendChild( navigation );

				for ( var section in list ) {

					// Create sections

					var categories = list[ section ];

					var sectionHead = document.createElement( 'h2' );
					sectionHead.textContent = section;
					navigation.appendChild( sectionHead );

					for ( var category in categories ) {

						// Create categories

						var pages = categories[ category ];

						var categoryContainer = document.createElement( 'div' );
						navigation.appendChild( categoryContainer );

						var categoryHead = document.createElement( 'h3' );
						categoryHead.textContent = category;
						categoryContainer.appendChild( categoryHead );

						var categoryContent = document.createElement( 'ul' );
						categoryContainer.appendChild( categoryContent );

						for ( var pageName in pages ) {

							// Create page links

							var pageURL = pages[ pageName ];

							var listElement = document.createElement( 'li' );
							categoryContent.appendChild( listElement );

							var linkElement = createLink( pageName, pageURL )
							listElement.appendChild( linkElement );

							// Gather the main properties for the current subpage

							pageProperties[ pageName ] = {
								section: section,
								category: category,
								pageURL: pageURL,
								linkElement: linkElement
							};

						// Gather the document titles (used for easy access on browser navigation)

						titles[ pageURL ] = pageName;

						}

						// Gather the category elements for easy access on filtering

						categoryElements.push( categoryContent );

					}

				}

			}


			// Filtering

			function updateFilter() {

				// (uncomment the following line and the "Query strings" section, if you want query strings):
				// updateQueryString();

				var regExp = new RegExp( filterInput.value, 'gi' );

				for ( var pageName in pageProperties ) {

					var linkElement = pageProperties[ pageName ].linkElement;
					var categoryClassList = linkElement.parentElement.classList;
					var filterResults = pageName.match( regExp );

					if ( filterResults && filterResults.length > 0 ) {

						// Accentuate matching characters

						for ( var i = 0; i < filterResults.length; i++ ) {

							var result = filterResults[ i ];

							if ( result !== '' ) {
								pageName = pageName.replace( result, '<b>' + result + '</b>' );
							}

						}

						categoryClassList.remove( 'hidden' );
						linkElement.innerHTML = pageName;

					} else {

						// Hide all non-matching page names

						categoryClassList.add( 'hidden' );

					}

				}

				displayFilteredPanel();

			}

			function displayFilteredPanel() {

				// Show/hide categories depending on their content
				// First check if at least one page in this category is not hidden

				categoryElements.forEach( function ( category ) {

					var pages = category.children;
					var pagesLength = pages.length;
					var sectionClassList = category.parentElement.classList;

					var hideCategory = true;

					for ( var i = 0; i < pagesLength; i ++ ) {

						var pageClassList = pages[ i ].classList;

						if ( ! pageClassList.contains( 'hidden' ) ) {

							hideCategory = false;

						}

					}

					// If and only if all page names are hidden, hide the whole category

					if ( hideCategory ) {

						sectionClassList.add( 'hidden' );

					} else {

						sectionClassList.remove( 'hidden' );

					}

				} );

			}


			// Routing

			function setUrlFragment( pageName ) {

				// Handle navigation from the subpages (iframes):
				// First separate the memeber (if existing) from the page name,
				// then identify the subpage's URL and set it as URL fragment (re-adding the member)

				var splitPageName = decomposePageName( pageName, '.', '.' );

				var currentProperties = pageProperties[ splitPageName[ 0 ] ];

				if ( currentProperties ) {

					window.location.hash = currentProperties.pageURL + splitPageName[ 1 ];

					createNewIframe();

				}

			}

			function createNewIframe() {

				// Change the content displayed in the iframe
				// First separate the member part of the fragment (if existing)

				var hash = window.location.hash.substring( 1 );
				var splitHash = decomposePageName( hash, '.', '#' );

				// Creating a new Iframe instead of assigning a new src is
				// a cross-browser solution to allow normal browser navigation;
				// - only assigning a new src would result in two history states each time.

				// Note: iframe.contentWindow.location.replace(hash) should work, too,
				// but it doesn't work in Edge with links from the subpages!

				var oldIframe;
				var subtitle;

				oldIframe = iframe;
				iframe = oldIframe.cloneNode();

				if(hash) {

					iframe.src = splitHash[ 0 ] + '.html' + splitHash[ 1 ];
					subtitle = ' - ' + titles[ splitHash[ 0 ] ] + splitHash[ 1 ];

				} else {

					iframe.src = '';
					subtitle = '';

				}

				document.body.replaceChild( iframe, oldIframe );
				document.title = 'three.js docs' + subtitle;

			}

			function decomposePageName( pageName, oldDelimiter, newDelimiter ) {

				// Helper function for separating the member (if existing) from the pageName
				// For example: 'Geometry.morphTarget' can be converted to
				// ['Geometry', '.morphTarget'] or ['Geometry', '#morphTarget']
				// Note: According RFC 3986 no '#' allowed inside of an URL fragment!

				var parts = [];

				var dotIndex = pageName.indexOf( oldDelimiter );

				if ( dotIndex !== -1 ) {

					parts = pageName.split( oldDelimiter );
					parts[ 1 ] = newDelimiter + parts[ 1 ];

				} else {

					parts[ 0 ] = pageName;
					parts[ 1 ] = '';

				}

				return parts;

			}

			//

			console.log([
				'    __     __',
				' __/ __\\  / __\\__   ____   _____   _____',
				'/ __/  /\\/ /  /___\\/ ____\\/ _____\\/ _____\\',
				'\\/_   __/ /   _   / /  __/ / __  / / __  /_   __   _____',
				'/ /  / / /  / /  / /  / / /  ___/ /  ___/\\ _\\/ __\\/ _____\\',
				'\\/__/  \\/__/\\/__/\\/__/  \\/_____/\\/_____/\\/__/ /  / /  ___/',
				'                                         / __/  /  \\__  \\',
				'                                         \\/____/\\/_____/'
			].join('\n'));


		</script>

		<script src="../build/three.min.js"></script> <!-- console sandbox -->

	</body>

</html>
